package ru.susu.algebra.centralunits.alternating.tex.local;

import ru.susu.algebra.centralunits.alternating.MathMethodWithInitializers;
import ru.susu.algebra.jtex.ITexElement;
import ru.susu.algebra.jtex.SimpleTexElementWithCode;
import ru.susu.algebra.jtex.StringTexElement;
import ru.susu.algebra.jtex.TexBeginEndElement;
import ru.susu.algebra.jtex.UnionTexElement;
import ru.susu.algebra.jtex.formula.FormulaTexElement;
import ru.susu.algebra.jtex.formula.GreekSymbols;
import ru.susu.algebra.jtex.formula.MathSymbols;
import ru.susu.algebra.jtex.utils.TexUtils;
import ru.susu.algebra.properties.IPropertySource;

/**
 * Генератор основной леммы о трех следах. Создает лемму описывающую общие формулы для следов, основанные
 * на представлении значений особых характеров A = (1 + b * sqrt(d)) / 2 = (1 - b) / 2 + bw.
 * p201 Frobenius G. Teoriya harakterov i predstavlenij grupp (ONTI, 1937)(ru)(600dpi)(T)(215s)_MAr_
 * След данного значения всегда будет равен единице
 *
 * @author akargapolov
 * @since: 07.10.2010
 */
public class MainLemmaAboutTracesGenerator extends MathMethodWithInitializers<ITexElement>
{
	public static final String LABEL = "main_lemma_about_traces";
	@Override
	protected ITexElement directRun(IPropertySource ps) throws Exception
	{
		UnionTexElement union = new UnionTexElement();
		union.addSubElement(StringTexElement.comment(MainLemmaAboutTracesGenerator.class.getSimpleName()));
		union.addSubElement(getMainLemma(ps));
		return union;
	}

	private ITexElement getMainLemma(IPropertySource ps) throws Exception
	{
		String doubleSlash = "," + MathSymbols.DOUBLE_INV_SLASH + "\n";
		String eqDoubleSlash = " = " + MathSymbols.DOUBLE_INV_SLASH + "\n" + " = ";
		String lambdaM1Brackets = TexUtils.inBrackets(GreekSymbols.LAMBDA + " - 1");
		String omega2 = GreekSymbols.OMEGA + TexUtils.pow("2");
		String alphaM1 = GreekSymbols.ALPHA + " - 1";
		String alphaM1Brackets = TexUtils.inBrackets(alphaM1);
		String lambdaInAlpha = GreekSymbols.ALPHA + " + " + GreekSymbols.BETA + GreekSymbols.OMEGA;
		String lambdaInAlpha1 = TexUtils.inBrackets(GreekSymbols.ALPHA + " - 1 + " + GreekSymbols.BETA + GreekSymbols.OMEGA);


		/*Пусть $\lambda=\alpha+\beta\omega$ и $A=a+b\omega$. Тогда
		\begin{align}
		\tr(\lambda-1)&=2(\alpha-1)+\beta,\\
		\tr(\texttt{A}(\lambda-1))&=(2a+b)(\alpha-1)+\frac{bd+2a+b}{2}\beta,\\
		\tr(\texttt{*A}(\lambda-1))&=(2a+b)(\alpha-1)+\frac{2a+b-bd}{2}\beta.
		\end{align}*/

		String onembBrac = TexUtils.inBrackets("1 - b");
		String onemb2 = FormulaTexElement.frac("1 - b", "2");
		String twoAPlusB = TexUtils.inBrackets("2" +onemb2 + "+b");
		TexBeginEndElement lemma = TexBeginEndElement.lemma();
		lemma.addSubElement(SimpleTexElementWithCode.label(LABEL));
		lemma.addSubElement(StringTexElement.text(
				"Пусть $" + GreekSymbols.LAMBDA + " = " + lambdaInAlpha + "$ и " +
				"$A = " + onemb2 + MathSymbols.PLUS  + " b" +  GreekSymbols.OMEGA + "$. Тогда\n"))
				.addSubElement(	TexBeginEndElement.align().addSubElement(StringTexElement.text(
				MathSymbols.TR + lambdaM1Brackets + " &= 2" + alphaM1Brackets + " + " + GreekSymbols.BETA + doubleSlash +
				MathSymbols.TR + TexUtils.inBrackets("A" + lambdaM1Brackets) + " &= " +
					alphaM1Brackets + MathSymbols.PLUS + FormulaTexElement.frac("1 + bd", "2") + GreekSymbols.BETA + doubleSlash +
				MathSymbols.TR + TexUtils.inBrackets("*A" + lambdaM1Brackets) + " &= " +
					alphaM1Brackets + MathSymbols.PLUS + FormulaTexElement.frac("1 - bd", "2") + GreekSymbols.BETA + ".")));

		//доказательство
		StringTexElement case1 = StringTexElement.text(
				MathSymbols.TR + lambdaM1Brackets + " = " +
				MathSymbols.TR + TexUtils.inBrackets(alphaM1Brackets + MathSymbols.PLUS + GreekSymbols.BETA + GreekSymbols.OMEGA) + " = " +
				"2" + alphaM1Brackets + MathSymbols.PLUS + GreekSymbols.BETA + doubleSlash);

		String aBeta = onemb2 + GreekSymbols.BETA;
		StringTexElement case2 = StringTexElement.text(
				MathSymbols.TR + TexUtils.inBrackets("A" + lambdaM1Brackets) + " = " +
				MathSymbols.TR + TexUtils.inBrackets(TexUtils.inBrackets(onemb2 + MathSymbols.PLUS  + " b" +  GreekSymbols.OMEGA) + lambdaInAlpha1) + eqDoubleSlash +
				MathSymbols.TR + TexUtils.inBrackets("b" + GreekSymbols.BETA + omega2 + MathSymbols.PLUS +
						TexUtils.inBrackets("b" + alphaM1Brackets + MathSymbols.PLUS + aBeta) + GreekSymbols.OMEGA + MathSymbols.PLUS +
						onemb2 + alphaM1Brackets) + eqDoubleSlash +
				"b" + GreekSymbols.BETA + FormulaTexElement.frac("d + 1", "2") + MathSymbols.PLUS +
						"b" + alphaM1Brackets + MathSymbols.PLUS + aBeta + MathSymbols.PLUS + "2" + onembBrac + alphaM1Brackets + eqDoubleSlash +
				alphaM1Brackets + MathSymbols.PLUS + FormulaTexElement.frac("bd + b + 1 - b", "2") + GreekSymbols.BETA + " = \n" +
				alphaM1Brackets + MathSymbols.PLUS + FormulaTexElement.frac("1 + bd", "2") + GreekSymbols.BETA + doubleSlash);

		String onemb2I = FormulaTexElement.frac("1 + b", "2");
		StringTexElement case3 = StringTexElement.text(
				MathSymbols.TR + TexUtils.inBrackets("*A" + lambdaM1Brackets) + " = " +
				MathSymbols.TR + TexUtils.inBrackets(TexUtils.inBrackets(onemb2 + "+b-b" + GreekSymbols.OMEGA) + lambdaInAlpha1) + " = \n" +
				MathSymbols.TR + TexUtils.inBrackets(TexUtils.inBrackets(onemb2I + "-b" + GreekSymbols.OMEGA) + lambdaInAlpha1) + eqDoubleSlash +
				alphaM1Brackets + MathSymbols.PLUS + FormulaTexElement.frac("1 - bd", "2") + GreekSymbols.BETA + ".");

		TexBeginEndElement proof = TexBeginEndElement.proof();
		proof.addSubElement(StringTexElement.text("В самом деле\n")).addSubElement(TexBeginEndElement.align().setWithoutNumber()
				.addSubElement(case1).addSubElement(case2).addSubElement(case3));

		return new UnionTexElement().addSubElement(lemma).addSubElement(proof).addSubElement(StringTexElement.newLine());
	}

	@Override
	protected Class[] getDependentInitializers()
	{
		return new Class[0];
	}

}